! Tic-tac-toe in F95 by Paul Dubois
!
program tictactoe
    use ttt_board
    use text_display
    type(board) the_board, history(0:9)
    type(move_spec) m
	type(player),pointer:: the_winner
    integer n_history, choice
	call position_module_initialize   
    call piece_module_initialize
    call player_module_initialize
    call board_module_initialize
    call display_module_initialize

    do 
        call display("Enter 1 to play X, 2 to play O: ")
        read(5, *) choice
        select case(choice)
        case(1)
            call set_controller(mrx, human_controller)
            call set_controller(mro, ai_controller)
            exit
        case(2)
            call set_controller(mrx, ai_controller)
            call set_controller(mro, human_controller)
            exit
        case default
            call display("Please choose 1 or 2.")
        end select
    enddo
        
    game_loop: do 
        call new(the_board)
		n_history = 0
        history(0) = the_board
        do while(incomplete(the_board))
            m = get_move(the_board)
            select case(m%code)
            case (quit_command) 
               exit game_loop
			case(undo_command) 
				n_history = max(0, n_history + m%x)
				the_board = history(n_history)
				cycle
            case(move_command)
                if(move(the_board, m)) then
			        n_history = n_history + 1
			        history(n_history) = the_board
			    else
                    call display("Sorry, illegal move, try again.")
                endif
            case default
                call display("Command not understood, please try again.")
            end select
        end do
        if(m%code == move_command) then
			the_winner => winner(the_board)
		    call record_win(the_winner)
            call display("The winner is "//as_string(the_winner))
		endif
        call display("Game over. Final position:")
        call display(the_board)
        call display("--------------------------------")

        call destroy(the_board)
    end do game_loop

	write(6, *) "X won ", number_of_wins(mrx), " games."
	write(6, *) "O won ", number_of_wins(mro), " games."
	write(6, *) number_of_wins(mrcat), " games were cat games."

    call display_module_finalize
    call board_module_finalize
    call player_module_finalize
    call piece_module_finalize
	call position_module_finalize

end program tictactoe